//
//  MyObject.m
//  ZXTimer_Example
//
//  Created by 朱新明 on 2023/5/31.
//  Copyright © 2023 simon. All rights reserved.
//

#import "MyObject.h"
#import "MyObject2.h"
#include <objc/runtime.h>

@implementation MyObject

@dynamic lineSpace;

- (void)hello:(NSString *)name{
    NSLog(@"HelloWorld,MyObject");
}

//void dynamicMethodIMP(id self, SEL _cmd, NSString *name)
//{
//    NSLog(@"实例：%@，方法名：%@，参数:%@",self,NSStringFromSelector(_cmd),name);
//}
void dynamicMethodIMPSetter(id self, SEL _cmd, CGFloat value)
{
    if (_cmd == @selector(setLineSpace:))
    {
        MyObject *obj = (MyObject *)self;
        obj.space = value;
    }
    NSLog(@"实例：%@，方法名：%@",self,NSStringFromSelector(_cmd));
}
CGFloat dynamicMethodIMPGetter(id self, SEL _cmd)
{
    if (_cmd == @selector(lineSpace))
    {
        MyObject *obj = (MyObject *)self;
        return obj.space;
    }
    return 0;
}

///动态解析方法：为给定selector动态提供一个实现
+ (BOOL)resolveInstanceMethod:(SEL)sel{
//    会有警告
//    if (sel == @selector(hi:))
//    if ([NSStringFromSelector(sel) isEqualToString:@"hi:"])
//    {
//        class_addMethod(self, sel, (IMP)dynamicMethodIMP, "v@:");
//        return YES;
//    }
    if (sel == @selector(setLineSpace:))
    {
        class_addMethod(self, sel, (IMP)dynamicMethodIMPSetter, "v@:");
        return YES;
    }
    else if (sel == @selector(lineSpace)){
        class_addMethod(self, sel, (IMP)dynamicMethodIMPGetter, "f@:");
        return YES;
    }
    return [super resolveInstanceMethod:sel];
}

//- (id)forwardingTargetForSelector:(SEL)aSelector{
//    if ([NSStringFromSelector(aSelector) isEqualToString:@"hi:"]) {
//        return [[MyObject2 alloc] init];
//    }
//    return [super forwardingTargetForSelector:aSelector];
//}

///要间接消息转发，需要返回一个有效的方法签名对象，系统才能创建Invocation消息进行消息转发。
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{

    if ([NSStringFromSelector(aSelector) isEqualToString:@"hi:"]){
        return [NSMethodSignature signatureWithObjCTypes:"v@:@"];
    }
    return [super methodSignatureForSelector:aSelector];
}

- (void)forwardInvocation:(NSInvocation *)anInvocation{
    SEL aSelector = anInvocation.selector;
    if ([NSStringFromSelector(aSelector) isEqualToString:@"hi:"]){
        MyObject2 *target = [MyObject2 new];
        [anInvocation invokeWithTarget:target];
    }else{
        [super forwardInvocation:anInvocation];
    }
}

@end
